<template>
  <div class="cont" ref="mapChart"></div>
  <div class="back-zj" v-if="isShowBackZj" @click="backZj">返回浙江省</div>
  <ul class="menu">
    <li 
      v-for="(item, index) in effectMenu" 
      :class="{active: currentIndex === index}" 
      :key="index" 
      @click="changeEffect(item.name, index)"
      >
      {{ item.name }}
    </li>
  </ul>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import * as echarts from 'echarts'
import ZJJson from '@/assets/mapJson/zhejiang.json'
import _ from 'lodash'

import type { ECharts, EChartsOption } from 'echarts'

import areaMaps, { areaPos } from '@/utils/map_utils'
import { scatter, trans, heat, seriesColor } from './config'
  let mapChart = ref()
  const initOption: EChartsOption = {
    backgroundColor: '#F0f2f5',
    geo:{
      map:'ZJ',
      roam:true,
      zoom: 1.2,
      scaleLimit: {
        min: 0.8,
        max: 2
      },
      label:{
        show: true,
        formatter: function (params) {
          return `{name|${params.name}}`;
        },
        rich:{
          name:{
            color:'#fff',
            padding:[3,3],
            borderWidth:1,
            borderColor:'#fff'
          }
        },
        fontWeight: "normal",
        fontSize: 12,
        color: "#fff"
      },
      emphasis: {
        label: {
          color: "#FFFFFF"
        },
        itemStyle: {
          areaColor: "#008affaa",
        },
      },
      itemStyle: {
        borderWidth: 1,
        borderColor: "#00fff6",
        areaColor:'#015ab6',
      },
      select:{
        itemStyle:{
          areaColor: "#008affaa"
        }
      }
    }
  }
  let map:ECharts
  const initMap = (option = initOption, mapJson = null) => {
    map && map.dispose()

    map = echarts.init(mapChart.value)
    echarts.registerMap('ZJ', mapJson || ZJJson as any)
    map.setOption(option)
    map.on('click', params => {
      isShowBackZj.value = true
      const currentItem = areaMaps.find(item => item.label === params.name)
      if (!currentItem) return
      initMap(option, currentItem.mapJson as any)
    })
  }

  const effectMenu = ref([
    { name: '基础地图' },
    { name: '热力图' },
    { name: '涟漪图' },
    { name: '多色地图' },
    { name: '运输路线' },
  ])
  const currentIndex = ref(0)
  const isShowBackZj = ref(false)
  const backZj = () => {
    initMap(initOption, ZJJson as any)
  }

  const changeEffect = (name: string, index) => {
    currentIndex.value = index
    switch (name) {
      case '基础地图':
        initMap()
        break;
      case '涟漪图':
        drawScatterChart()
        break;
      case '运输路线':
        drawTransChart()
        break
      case '热力图':
        drawHeatChart()
        break
      case '多色地图':
      drawSeriesColorChart()
        break
      default:
        break;
    }
  }

  let scatterData = ref(scatter)
  const drawScatterChart = () => {
    let data: any[] = []
    scatterData.value.forEach(item => {
      const area = areaPos.find(Iitem => Iitem.name === item.name)
      if (area) {
        const pos = area.lnglat.split(",");
        data.push({
          value: [ pos[0], pos[1], item.count ],
        });
      }
    })
    let option = _.cloneDeep(initOption);
    option.series = [{
      type: "effectScatter",
      showEffectOn: "render",
      coordinateSystem: "geo",
      symbol: (value) => {
        const count = value[2];
        if (count > 6) {
          return `image://${new URL('../../../assets/images/red_warning.png', import.meta.url).href}`
        } else {
          return `image://${new URL('../../../assets/images/chengWarning.png', import.meta.url).href}`
        }
      },
      symbolOffset: [35, 15],
      symbolSize: [25, 25],
      rippleEffect: {
        period: 5,
        scale: 6,
        brushType: "fill",
      },
      data,
    }];
    initMap(option)
  }

  const transData = ref(trans)
  const drawTransChart = () => {
    let option = _.cloneDeep(initOption);
    let data: any[] = [];
    let symbolStartData: any[] = []
    let symbolEndData: any[] = []
    const lineColorArr = [ "#ffffff", "#ffeb66", "#ff7800", "#01edfb", "f21333", "01fb59" ];
    transData.value.forEach((item, index) => {
      const start = areaPos.find( area => area.name === item.start.city);
      const end = areaPos.find((area) => area.name === item.end.city);
      if (start && end) {
        const startPos = item.startCoordinate.split(",").reverse();
        const endPos = item.endCoordinate.split(",").reverse();
        symbolStartData.push({
          value: [startPos[0], startPos[1]]
        })
        symbolEndData.push({
          value: [endPos[0], endPos[1]]
        })
        data.push({
          fromName: item.start.city,
          toName: item.end.city,
          value: 1,
          coords: [
            [startPos[0], startPos[1]],
            [endPos[0], endPos[1]],
          ],
          lineStyle: {
            color: lineColorArr[index],
            width: 2,
            curveness: 0.2,
          },
        });
      }
    });
    option.series = [
      {
        type: "lines",
        zlevel: 10,
        effect: {
          show: true,
          period: 3,
          trailLength: 0,
          symbol: "arrow",
          symbolSize: 6,
        },
        data,
      },
      {
        type: "effectScatter",
        showEffectOn: "render",
        coordinateSystem: "geo",
        symbol: () => {
          return `image://${new URL('../../../assets/images/qidian.png', import.meta.url).href}`
        },
        symbolSize: [20, 20],
        rippleEffect: {
          period: 5,
          scale: 0,
          brushType: "fill",
        },
        data: symbolStartData
      },
      {
        type: "effectScatter",
        showEffectOn: "render",
        coordinateSystem: "geo",
        symbol: () => {
          return `image://${new URL('../../../assets/images/zhongdian.png', import.meta.url).href}`
        },
        symbolSize: [20, 20],
        rippleEffect: {
          period: 5,
          scale: 0,
          brushType: "fill",
        },
        data: symbolEndData
      }
    ];
    initMap(option)
  }

  const headData = ref(heat)
  const drawHeatChart = () => {
    let areaData: any[] = [];
    headData.value.map(item => {
        areaData.push(...new Array(3).fill(item));
    });
    let mapMax = Math.max(...headData.value.map(item => item[2]));
    let mapMin = Math.min(...headData.value.map(item => item[2]));

    let option = _.cloneDeep(initOption)

    option.visualMap = {
      bottom: 20,
      left: 10,
      show: true,
      color: ['#ff4601', '#fffc00', '#87cffa'],
      min: mapMin,
      max: mapMax,
      calculable: true,
      textStyle: {
        color: '#fff',
        fontSize: 12
      }
    }
    option.series = [{
      name: 'AQI',
      type: 'heatmap',
      coordinateSystem: 'geo',
      blurSize: 40,
      data: areaData,
    }]

    initMap(option)
  }

  const seriesColorData = ref(seriesColor)
  const drawSeriesColorChart = () => {
    let option = _.cloneDeep(initOption);
    option.visualMap = {
      min: 0,
      max: 100000,
      left: 26,
      bottom: 40,
      showLabel: true,
      pieces: [{
        gt: 0.7,
        label: "70%-100%",
        color: "rgba(38,100,174,0.4)"
      }, {
        gte: 0.3,
        lte: 0.7,
        label: "30%-70%",
        color: "rgba(211,173,21,0.4)"
      }, {
        gte: 0,
        lt: 0.3,
        label: "0%-30%",
        color: "rgba(185,111,22,0.4)"
      }],
      show: true
    }
    const series: any = [{
      type: "map",
      geoIndex: 0,
      data: seriesColorData.value
    }]
    option.series = series
    initMap(option)
  }

  onMounted(() => {
    initMap()
  })
</script>

<style scoped lang="less">
.cont {
  height: 90%;
}
.menu {
  display: flex;
  justify-content: space-around;
  li {
    width: 120px;
    height: 30px;
    line-height: 30px;
    border-radius: 30px;
    border: 1px solid pink;
    cursor: pointer;
  }
}
.back-zj {
  cursor: pointer;
  color: rgb(86, 237, 237);
}
.active {
  background-color: pink;
}
</style>